#!/usr/bin/env python
# -*- coding:utf-8 -*-

'''
Created on 2011-9-19

@author: zhongfeng
'''

import re,os,sys,itertools,glob
from dbproc.basedbproc import *
from decimal import Decimal

def wrapDecimal(priceStr):
    return Decimal(str(priceStr))

def calRealPrice(curPrice, coupon, orderCut, crashCut,extraCut):
    
    return str(float(wrapDecimal(curPrice) - wrapDecimal(coupon) -
                      wrapDecimal(orderCut) - wrapDecimal(crashCut) - wrapDecimal(extraCut)))
    
class PriceInfoBuilder(object):
    def __init__(self,adWords,curPrice = 0.00,extraCut = 0.00):
        self.adWords = adWords
        self.curPrice = curPrice
        self.extraCut = extraCut       
    def getCoupon(self):
        '''返券'''
        return '0.00'
    def getExGift(self):
        '''赠品'''
        return ''   
    def getOrderCut(self):
        '''下单立减'''
        return '0.00'  
    def getCrashCut(self):
        '''返现'''
        return '0.00'
    def getCurPrice(self):
        '''商品标价'''
        return self.curPrice
    
    def getSiteDefineFinalPrice(self):
        '''网站标注的商品实际成交价（折算返券、赠品等等）'''
        return '0.00'
    
    def getRealPrice(self):
        '''商品计算后得到的价格'''
        fPrice = self.getSiteDefineFinalPrice() 
        if fPrice != '0.00':
            return fPrice
        return calRealPrice(self.curPrice ,self.getCoupon(),
                                self.getOrderCut(),self.getCrashCut(),self.extraCut)

class J360PriceInfoBuilder(PriceInfoBuilder):
    def __init__(self, adWords, curPrice=0.00, extraCut=0.00):
        PriceInfoBuilder.__init__(self, adWords, curPrice=curPrice, extraCut=extraCut)
    
    def getCoupon(self):
        p1 = re.compile(ur'([0-9]+)元?京?券')
        p2 = re.compile(ur'京?券([0-9]+)')
        ret1 = p1.search(self.adWords)
        ret = ret1 if ret1 != None else p2.search(self.adWords)
        if ret != None:
            return ret.group(1)
        else:
            return '0.00'

    def getExGift(self):
        i = self.adWords.rfind(u'赠')#//送
        if i != -1:
            ret = self.adWords[i:].replace(u'，', ' ').replace(u'！', ' ')
            ti = ret.find(' ')
            if ti != -1:
                return ret[0:ti]
            else:
                return ret
        else:
            return ''

    def getOrderCut(self):
        p1 = re.compile(ur'下单.*减([0-9]+)')
        p2 = re.compile(ur'下单直降([0-9]+)')
        ret1 = p1.search(self.adWords)
        ret = ret1 if ret1 != None else p2.search(self.adWords)
        if ret != None:
            return ret.group(1)
        else:
            return '0.00'   
    
    def getCrashCut(self):
        p1 = re.compile(ur'返现([0-9]+)')
        ret1 = p1.search(self.adWords)
        if ret1 != None:
            return ret1.group(1)
        else:
            return '0.00'
    
    def getSiteDefineFinalPrice(self):
        p1 = re.compile(ur'相当于([0-9]+)')
        p2 = re.compile(ur'成交价?([0-9]+)')
        p3 = re.compile(ur'([0-9]+)元?成交')
        ret1 = p1.search(self.adWords)
        ret2 = ret1 if ret1 != None else p2.search(self.adWords)
        ret = ret2 if ret2 != None else p3.search(self.adWords)
        if ret != None:
            return ret.group(1)
        else:
            return '0.00'

#===============================================================================
# Product 基础信息入库处理
#===============================================================================
def parserProdBaseInfo(site_id, prodIdsDict, line):
    ret = line.split('|')
    if len(ret) != 10:   #格式列不对
        return
    raw_id = ret[0]
    if prodIdsDict.get(raw_id,None) != None:  #判断库里是否已经存在
        return 
    prodIdsDict[raw_id] = 'exist'  #保证文件里的同一个商品只入库一次
    
    catUrl = eval(ret[-1])[0]
    cat_id = getCatIdFromRawInfo(site_id, catUrl)  #有问题，如果有新的类别加入，应该怎样？
      
    name = ret[3]
    repu = ret[4]
    eval_num = ret[5]
    url = ret[7]
    img_url = ret[8]
    u_time = ret[2]
    param = (site_id, raw_id, name, url, img_url, repu, 
             eval_num, cat_id, u_time)
    return param

def getLine(fileName,encoding='gb18030'):
    ''' 处理文件 '''
    with open(fileName, 'r') as fInput:
        for line in fInput:
            yield line.strip().decode(encoding, 'ignore')
            
def createProdBaseInfo(siteName, fileName):
    ''' 商品基本信息批量入库 '''
    site_id = getSiteIdByName(siteName)
    conn = getConnect()
    params = list()
    i = 0
    prodIdsDict = getProdInfoRawIDMapId(site_id)
    for line in getLine(fileName):
        param = parserProdBaseInfo(site_id, prodIdsDict, line)
        if param is None:
            continue
        print 'create prod base info %s,%s' % (param[1],param[2])
        params.append(param)
        i = i + 1
        if i == 200:
            batchSaveProdBaseInfo(conn, params)
            params = list()
            i = 0
    if i > 0:
        batchSaveProdBaseInfo(conn, params)
        del params      
    conn.close()
    
def procDbLatestPriceInfo(conn,prod_id,u_time,real_price,cur_price):
    ret = getProdPriceInfoFromProdId(conn,prod_id=prod_id)
    if ret is None:
        return '0.00'
    cur_date = u_time.split()[0]
    date_list = [it[2].strftime("%Y-%m-%d") for it in ret]
    for v in date_list:
        if cmp(cur_date, v) == 0:#同一天的不重复入库，当一天多次抓的时候，会有问题
            #print prod_id,u_time
            return
    #    elif cmp(cur_date,v) < 0:
    #        retPrices = ret[i][0:2]
    #        break
    if cmp(cur_date,ret[0][2].strftime("%Y-%m-%d")) < 0:
        return
    retPrices = ret[0][0:2]
    if retPrices != None and wrapDecimal(real_price) == wrapDecimal(retPrices[0]) and  wrapDecimal(cur_price) == wrapDecimal(retPrices[1]):
        return
    elif retPrices is None:
        diff_price = 0.00
    else:
        diff_price = (wrapDecimal(real_price) - wrapDecimal(retPrices[0]))
    
    return diff_price
    

def parserProdPriceInfo(conn,site_id, line, raw_id_set, prodIdsDict, BuilderClass):
    ret = line.split('|')
    if len(ret) != 10:
        return
    raw_id = ret[0]
    if raw_id in raw_id_set:
        return 
    raw_id_set.add(raw_id)
    cur_price = ret[1]
    if str(cur_price) == '0.00':
        #print 'Price is 0.00 %s,' % line
        return
    u_time = ret[2]
    adwords = ret[6]
    builder = BuilderClass(adWords=adwords, curPrice=cur_price)
    coupon = builder.getCoupon()
    ex_gift = builder.getExGift()
    order_cut = builder.getOrderCut()
    crash_cut = builder.getCrashCut()
    real_price = builder.getRealPrice()
    prod_id = prodIdsDict.get(raw_id, None)
    if prod_id is None:
        #return
        param = parserProdBaseInfo(site_id, prodIdsDict, line)
        param_c = list()
        param_c.append(conn)
        param_c.extend(param)
        prod_id = saveProdBaseInfo(*param_c)
        prodIdsDict[raw_id] = prod_id
        print 'new prod raw_id:%s,id:%s,name:%s'  % (raw_id,prod_id,param[2])
    diff_price = procDbLatestPriceInfo(conn,prod_id,u_time,real_price,cur_price)
    if diff_price is None :
        return
    param = (prod_id, real_price, cur_price, 0.00, diff_price, 0.00, 0.00, adwords, coupon, ex_gift, order_cut, crash_cut, u_time)
    return param

def createProdPriceInfo(siteName,fileName, PriceInfoBuilderClass = PriceInfoBuilder, encoding='gb2312'):
    site_id = getSiteIdByName(siteName)    
    prodIdsDict = dict(getAllRawProdIdsBySite(site_id))#key:raw_id value:id
    if len(prodIdsDict) == 0:
        createProdBaseInfo(siteName,fileName,encoding)
        prodIdsDict = dict(getAllRawProdIdsBySite(site_id))
    i = 0
    params = list()
    raw_id_set = set()
    conn = getConnect()
    with open(fileName, 'r') as fInput:
        for line in fInput:
            line = line.strip().decode(encoding, 'ignore')
            param = parserProdPriceInfo(conn,site_id, line, raw_id_set, 
                                        prodIdsDict, PriceInfoBuilderClass)
            if param is None:
                continue
            print 'create prod price info %s,%s' % (param[0],param[4])
            params.append(param)
            i = i + 1
            if i == 200:
                batchSaveProdPriceInfo(conn, params)
                params = list()
                i = 0
    if i > 0:
        batchSaveProdPriceInfo(conn, params)
        del params
    #saveProdPriceInfo(conn, prod_id=prod_id, real_price=real_price, cur_price=cur_price,diff_price = 0.00, adwords=adwords,
    #                           coupon=coupon, ex_gift=ex_gift,order_cut=order_cut, crash_cut=crash_cut)
    conn.close()

def __getDateStrFromFileName(fName):
    p = re.compile('[0-9]{4}-[0-9]{2}-[0-9]{2}')
    ret = p.search(fName)
    if ret != None:
        return ret.group()
    
def loadDataToDB(files,beginDate = None,endDate = None):
    for fileName in itertools.chain(files[1:],files[0:1]):
        fName = os.path.split(fileName)[-1]
        dateStr = __getDateStrFromFileName(fName)
        if beginDate != None and dateStr != None and cmp(dateStr,beginDate) < 0:
            continue
        elif endDate != None and dateStr != None and cmp(dateStr,endDate) > 0:
            break   
        siteName = fName.split('_')[0]
        print fileName
        if siteName == '360buy':      
            createProdPriceInfo(siteName, fileName, J360PriceInfoBuilder)  
        else:
            createProdPriceInfo(siteName, fileName)
           
if __name__ == '__main__':
    #createProdBaseInfo('amazon',r'I:\log\amazon\amazon_spider.log.2011-09-20')
    rootBase = r'I:\log'
    for rootDir in os.listdir(rootBase):
        if rootDir.find('.') >= 0:
            continue
        rootDir = os.path.join(rootBase,rootDir)
        if os.path.isdir(rootDir):
            plog = r'%s%s*log*' % (rootDir,os.sep)
            files = glob.glob(plog)
            print files
            loadDataToDB(files,beginDate = '2011-10-03',endDate='2011-10-03')
     
